﻿Imports <xmlns:c="http://www.professionalvisualstudio.com/chapter24/customers">
Imports System.Collections.Generic

Public Class MainForm

#Region "Samplizer"
    Private Class ComboItem
        Public Name As String
        Public Query As Reflection.MethodInfo
        Public Overrides Function ToString() As String
            Return Name
        End Function
    End Class

    Private Class SampleAttribute
        Inherits Attribute
        Public Name As String
        Public Sub New(ByVal sampleName As String)
            Name = sampleName
        End Sub
    End Class

    Private Sub MainForm_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim methods = GetType(MainForm).GetMethods(Reflection.BindingFlags.Instance Or _
                                                 Reflection.BindingFlags.InvokeMethod Or _
                                                 Reflection.BindingFlags.NonPublic Or _
                                                 Reflection.BindingFlags.Public)
        For Each mthd In methods
            Dim attributes = mthd.GetCustomAttributes(GetType(SampleAttribute), False)
            If attributes IsNot Nothing AndAlso attributes.Length > 0 Then
                Me.cboSamples.Items.Add(New ComboItem With {.Name = CType(attributes(0), SampleAttribute).Name, .Query = mthd})
            End If
        Next
    End Sub

    Private Sub btnRun_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRun.Click
        Dim ci = TryCast(Me.cboSamples.SelectedItem, ComboItem)
        If ci Is Nothing Then Return
        mOutStream = New IO.StringWriter
        ci.Query.Invoke(Me, Nothing)
        mOutStream.Flush()
        Dim output As String = mOutStream.ToString
        If output.Length > 0 Then
            Me.txtOutput.Text = output
        End If
        mOutStream.Close()
        mOutStream = Nothing
    End Sub
#End Region

    Private mOutStream As IO.StringWriter


    

    <Sample("XML Literal")> _
    Private Sub XMLLiteral()
        Dim cust = <Customers>
                       <Customer Name="Bob Jones">
                           <Order Product="Milk" Quantity="2"/>
                           <Order Product="Cereal" Quantity="10"/>
                           <Order Product="Milk" Quantity="5"/>
                       </Customer>
                   </Customers>

        Me.txtOutput.Text = cust.ToString
    End Sub

    <Sample("XML CSharp")> _
    Private Sub XMLCsharp()
        Dim cust = CLinq.CustomerQueries.XMLLiteral

        Me.txtOutput.Text = cust.ToString
    End Sub

    <Sample("Create Customer XML")> _
    Private Sub CreateCustomerXML()
        Dim customers As Customer() = BuildCustomers()

        Dim customerXml = <Customers>
                              <%= From c In customers _
                                  Let Name = c.FirstName & " " & c.LastName _
                                  Order By Name _
                                  Select <Customer Name=<%= Name %>>
                                             <%= From o In c.Orders _
                                                 Select <Order
                                                            Product=<%= o.Product %>
                                                            Quantity=<%= o.Quantity %>
                                                        /> %>
                                         </Customer> %>
                          </Customers>
        Me.txtOutput.Text = customerXml.ToString
    End Sub

    <Sample("Create Customer XML (CSharp)")> _
    Private Sub CreateCustomerXMLCSharp()
        Dim customers As Customer() = BuildCustomers()

        Dim customerXml = CLinq.CustomerQueries.CreateCustomerXML(customers)
        Me.txtOutput.Text = customerXml.ToString
    End Sub

    <Sample("Read Customer XML")> _
    Private Sub ReadCustomerXML()
        Dim customerXml = BuildCustomerXML()

        Dim results = From cust In customerXml.<Customer> _
                      Select cust.@Name

        ObjectDumper.Write(results, log:=Me.mOutStream)
    End Sub

    <Sample("Read Customer XML into Customer")> _
    Private Sub ReadCustomerXMLIntoCustomer()
        Dim customerXml = BuildCustomerXML()


        Dim results = From cust In customerXml.<Customer> _
                      Let nameBits = cust.@Name.Split(" "c) _
                      Select New Customer() With {.FirstName = nameBits(0), _
                                                    .LastName = nameBits(1)}

        ObjectDumper.Write(results, log:=Me.mOutStream)
    End Sub

    <Sample("Read Customer XML into Customer, with Orders")> _
    Private Sub ReadCustomerXMLIntoCustomerWithOrders()
        Dim customerXml = BuildCustomerXML()

        Dim results = From cust In customerXml.<Customer> _
                      Let nameBits = cust.@Name.Split(" "c) _
                      Select New Customer() With {.FirstName = nameBits(0), _
                                                    .LastName = nameBits(1), _
                                                    .Orders = (From o In cust.<Order> _
                                                               Select New Order() With {.Product = o.@Product, .Quantity = CInt(o.@Quantity)}).ToArray}

        ObjectDumper.Write(results, 1, log:=Me.mOutStream)
    End Sub


    <Sample("Read XML into Customer (CSharp)")> _
    Private Sub ReadCustomerXMLIntoCustomerCsharp()
        Dim customerXml = BuildCustomerXML()

        Dim results = CLinq.CustomerQueries.ReadCustomerXMLIntoCustomer(customerXml)

        ObjectDumper.Write(results, log:=Me.mOutStream)
    End Sub

    <Sample("Create Customer XML with Namespace")> _
    Private Sub CreateCustomerXMLWithNamespace()
        Dim customers As Customer() = BuildCustomers()

        Dim customerXml = <c:Customers>
                              <%= From c In customers _
                                  Select <c:Customer Name=<%= c.FirstName & " " & c.LastName %>>
                                             <%= From o In c.Orders _
                                                 Select <c:Order Product=<%= o.Product %> Quantity=<%= o.Quantity %>/> %>
                                         </c:Customer> %>
                          </c:Customers>

        Dim results = (From c In customerXml.<c:Customer> _
                      Select c.@Name).First

        MsgBox(results)

        Me.txtOutput.Text = customerXml.ToString
    End Sub


    Private Function BuildCustomers() As Customer()
        Return New Customer() {New Customer() With {.FirstName = "Bob", .LastName = "Jones", .Email = "bob@random.com", .Phone = "+61 010 010 010", .Orders = New Order() {New Order With {.Product = "Milk", .Quantity = 2}, New Order With {.Product = "Cereal", .Quantity = 10}, New Order With {.Product = "Milk", .Quantity = 5}}}, _
                               New Customer() With {.FirstName = "Alastair", .LastName = "Kelly", .Email = "al@random.com", .Phone = "+61 010 010 010", .Orders = New Order() {New Order With {.Product = "Milk", .Quantity = 9}, New Order With {.Product = "Bread", .Quantity = 7}, New Order With {.Product = "Milk", .Quantity = 6}, New Order With {.Product = "Pears", .Quantity = 8}}}, _
                               New Customer() With {.FirstName = "Jenny", .LastName = "Jackson", .Email = "jenny@random.com", .Phone = "+61 010 010 010", .Orders = New Order() {New Order With {.Product = "Eggs", .Quantity = 15}, New Order With {.Product = "Apples", .Quantity = 4}, New Order With {.Product = "Milk", .Quantity = 1}}}, _
                               New Customer() With {.FirstName = "Crystal", .LastName = "Major", .Email = "cm@random.com", .Phone = "+61 010 010 010", .Orders = New Order() {New Order With {.Product = "Eggs", .Quantity = 15}, New Order With {.Product = "Apples", .Quantity = 4}, New Order With {.Product = "Milk", .Quantity = 7}}}}
    End Function

    Private Function BuildCustomerXML() As XElement
        Dim customers As Customer() = BuildCustomers()

        Dim customerXml = <Customers>
                              <%= From c In customers _
                                  Select <Customer Name=<%= c.FirstName & " " & c.LastName %>>
                                             <%= From o In c.Orders _
                                                 Select <Order Product=<%= o.Product %> Quantity=<%= o.Quantity %>/> %>
                                         </Customer> %>
                          </Customers>
        Return customerXml
    End Function
End Class



